package com.dh.convert.rule.function;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.function.FunctionUtils;
import com.googlecode.aviator.runtime.type.AviatorNil;
import com.googlecode.aviator.runtime.type.AviatorObject;
import com.googlecode.aviator.runtime.type.AviatorRuntimeJavaType;


public class ExtMapFunction extends AbstractFunction {

 @Override
 @SuppressWarnings("unchecked")
 public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {

   Object first = arg1.getValue(env);
   if (first == null) {
     return AviatorNil.NIL;
   }
   String expression = FunctionUtils.getStringValue(arg2, env);
   if(StringUtils.isBlank(expression)){
   	throw new NullPointerException("expression is null");
   }
   Class<?> clazz = first.getClass();

   if (Collection.class.isAssignableFrom(clazz)) {
     Collection<Object> result = null;
     try {
       result = (Collection<Object>) clazz.newInstance();
     } catch (Throwable t) {
       // ignore
       result = new ArrayList<Object>();
     }
     for (Object obj : (Collection<?>) first) {
       env.put("ENTRY", obj);
       result.add(AviatorEvaluator.execute(expression, env, Boolean.TRUE));
     }
     return new AviatorRuntimeJavaType(result);
   } else if (clazz.isArray()) {
     // Object[] seq = (Object[]) first;
     int length = Array.getLength(first);
     Object result = Array.newInstance(Object.class, length);
     int index = 0;
     for (int i = 0; i < length; i++) {
       Object obj = Array.get(first, i);
       env.put("ENTRY", obj);
       Array.set(result, index++, AviatorEvaluator.execute(expression, env, Boolean.TRUE));
     }
     return new AviatorRuntimeJavaType(result);
   } else {
     throw new IllegalArgumentException(arg1.desc(env) + " is not a seq");
   }

 }


 @Override
 public String getName() {
   return "extMap";
 }

}

